4. Copies and Views
================

When operating and manipulating arrays, their data is sometimes copied
into a new array and sometimes not. This is often a source of confusion
for beginners. There are three cases:

4.1 No Copy at All
--------------

Simple assignments make no copy of array objects or of their data.

>>> a = np.arange(12)
>>> b = a            # no new object is created
>>> b is a           # a and b are two names for the same ndarray object
True
>>> b.shape = 3,4    # changes the shape of a
>>> a.shape
(3, 4)

Python passes mutable objects as references, so function calls make no
copy.

>>> def f(x):
...     print(id(x))
...
>>> id(a)                           # id is a unique identifier of an object
148293216
>>> f(a)
148293216

[demo]

import numpy as np
a = np.arange(12)
b = a
print(b is a)
b.shape = 3,4
print(a.shape)
def f(x):
    print(id(x))

print(id(a))
print(f(a))

[/demo]


4.2 View or Shallow Copy
--------------------

Different array objects can share the same data. The ``view`` method
creates a new array object that looks at the same data.

>>> c = a.view()
>>> c is a
False
>>> c.base is a                        # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6                      # a's shape doesn't change
>>> a.shape
(3, 4)
>>> c[0,4] = 1234                      # a's data changes
>>> a
array([[   0,    1,    2,    3],
[1234,    5,    6,    7],
[   8,    9,   10,   11]])

Slicing an array returns a view of it:

>>> s = a[ : , 1:3]     # spaces added for clarity; could also be written "s = a[:,1:3]"
>>> s[:] = 10           # s[:] is a view of s. Note the difference between s=10 and s[:]=10
>>> a
array([[   0,   10,   10,    3],
[1234,   10,   10,    7],
[   8,   10,   10,   11]])

[demo]

import numpy as np
a = np.arange(12)
c = a.view()
print(c is a)
print(c.base is a)
print(c.flags.owndata)
c.shape = 2,6
print(a.shape)
c[0,4] = 1234
print(a)
s = a[ : , 1:3]
s[:] = 10
print(a)


[/demo]



4.3 Deep Copy
---------

The ``copy`` method makes a complete copy of the array and its data.


>>> d = a.copy()                          # a new array object with new data is created
>>> d is a
False
>>> d.base is a                           # d doesn't share anything with a
False
>>> d[0,0] = 9999
>>> a
array([[   0,   10,   10,    3],
[1234,   10,   10,    7],
[   8,   10,   10,   11]])

[demo]

import numpy as np
a = np.arange(12)
d = a.copy()
print(d is a)
print(d.base is a)
d[0,0] = 9999
print(a)

[/demo]



4.4 Functions and Methods Overview
------------------------------

Here is a list of some useful NumPy functions and methods names
ordered in categories. See :ref:`routines` for the full list.

Array Creation
`arange`,
`array`,
`copy`,
`empty`,
`empty_like`,
`eye`,
`fromfile`,
`fromfunction`,
`identity`,
`linspace`,
`logspace`,
`mgrid`,
`ogrid`,
`ones`,
`ones_like`,
`r`,
`zeros`,
`zeros_like`
Conversions
`ndarray.astype`,
`atleast_1d`,
`atleast_2d`,
`atleast_3d`,
`mat`
Manipulations
`array_split`,
`column_stack`,
`concatenate`,
`diagonal`,
`dsplit`,
`dstack`,
`hsplit`,
`hstack`,
`ndarray.item`,
`newaxis`,
`ravel`,
`repeat`,
`reshape`,
`resize`,
`squeeze`,
`swapaxes`,
`take`,
`transpose`,
`vsplit`,
`vstack`
Questions
`all`,
`any`,
`nonzero`,
`where`
Ordering
`argmax`,
`argmin`,
`argsort`,
`max`,
`min`,
`ptp`,
`searchsorted`,
`sort`
Operations
`choose`,
`compress`,
`cumprod`,
`cumsum`,
`inner`,
`ndarray.fill`,
`imag`,
`prod`,
`put`,
`putmask`,
`real`,
`sum`
Basic Statistics
`cov`,
`mean`,
`std`,
`var`
Basic Linear Algebra
`cross`,
`dot`,
`outer`,
`linalg.svd`,
`vdot`